/**
 * 微信小程序相关
 */
import { Config, Inject, Provide } from "@midwayjs/core";
import { CacheManager } from "@midwayjs/cache";
import { AttachService } from "./att.service";
import * as fs from "fs";
import * as path from "path";

@Provide()
export class WxService {
  @Config("wxapp")
  private wxapp: {
    appid: string;
    secret: string;
    grant_type: string;
    access_token_url: string;
    access_token_cache_key: string;
    reward_page_path: string;
    env_version: "develop" | "release" | "trial";
    check_path: boolean;
    qrcode_url: string;
    is_hyaline: boolean;
  };

  @Inject()
  private cacheManager: CacheManager;

  @Inject()
  private attachService: AttachService;

  @Config("upload.tmpdir")
  tmpdir: string;

  async getAccessToken() {
    const accessToken = await this.cacheManager.get<string>(
      this.wxapp.access_token_cache_key
    );
    if (accessToken) return accessToken;

    const url = `${this.wxapp.access_token_url}?grant_type=${this.wxapp.grant_type}&appid=${this.wxapp.appid}&secret=${this.wxapp.secret}`;
    const resp = await fetch(url);
    if (resp.status === 200) {
      const json = (await resp.json()) as {
        access_token: string;
        expires_in: number;
      };
      await this.cacheManager.set(
        this.wxapp.access_token_cache_key,
        json.access_token,
        {
          ttl: json.expires_in - 60
        }
      );
      return json.access_token;
    } else {
      return "";
    }
  }

  /**
   * 获取微信小程序码
   * @param scene 场景id
   * @param activity 活动批次id
   * @returns
   */
  async getWxAppRewardCode(scene: string, activity?: string) {
    const accessToken = await this.getAccessToken();
    const url = `${this.wxapp.qrcode_url}?access_token=${accessToken}`;
    const data: any = {
      page: this.wxapp.reward_page_path,
      check_path: this.wxapp.check_path,
      env_version: this.wxapp.env_version,
      is_hyaline: this.wxapp.is_hyaline,
      width: 280,
      scene
    };

    const resp = await fetch(url, {
      method: "POST",
      headers: {
        "Content-Type": "application/json"
      },
      body: JSON.stringify(data)
    });

    if (resp.status !== 200) {
      const errorData = await resp.json();
      console.log("resp.status !== 200");
      console.log(errorData);
      return { success: false, message: errorData.errmsg, data: null };
    } else {
      const arrayBuffer = await resp.arrayBuffer();
      const buffer = Buffer.from(arrayBuffer);

      const result = await this.attachService.putCosBufferObject(
        buffer,
        scene + ".jpg",
        "image/jpeg",
        activity
      );

      if (result.success && result.data.attId) {
        const activityDir = path.join(this.tmpdir, activity);
        if (!fs.existsSync(activityDir)) {
          fs.mkdirSync(activityDir, { recursive: true });
        }
        const filePath = path.join(activityDir, scene + ".jpg");
        fs.writeFileSync(filePath, buffer);
      }

      return result;
    }
  }
}
